import json
import time
from PySide6.QtCore import QDateTime, QSettings, Slot, Qt, Signal, QObject
from PySide6.QtWidgets import QDialog, QTableWidgetItem
from Communicate.BleFunction.BleClient import BleClient
from Communicate.BleFunction.BleDeviceInfo import BleDeviceInfo
from Communicate.BleFunction.BleDiscover import BleDiscover
from Forms.BleFunctionWindow_UI import Ui_FormBleFunction
from Funcs.Config import Config

class BleFunctionWindow(QDialog, Ui_FormBleFunction):
    DefaultColor = Qt.black
    ChangeColor = Qt.blue
    
    def __init__(self, parent = None):
        super().__init__()
        self.setupUi(self)

        flags = self.windowFlags()
        self.setWindowFlags(flags & ~Qt.WindowContextHelpButtonHint)

        self.tableWidget_Devices.setColumnWidth(0, 230)
        self.tableWidget_Devices.setColumnWidth(1, 140)
        
        self.__bleFunction = BleDiscover()
        self.__bleFunction.DiscoverStartd.connect(self.on_DiscoverStartd)
        self.__bleFunction.DiscoverStopped.connect(self.on_DiscoverStopped)
        self.__bleFunction.DeviceDiscovered.connect(self.on_DeviceDiscovered)

        self.__bleClient = None

        self.__sentColor = BleFunctionWindow.ChangeColor
        self.__recvColor = BleFunctionWindow.ChangeColor

        s = QSettings(Config.ConfigIniPath(), QSettings.IniFormat)
        s.beginGroup("UI")
        s.beginGroup("BleFunctionWindow")

        if not s.value("lineEdit_Pwd") is None:
            self.lineEdit_Pwd.setText(s.value("lineEdit_Pwd"))

        if not s.value("plainTextEdit_Msg") is None:
            self.plainTextEdit_Msg.setPlainText(s.value("plainTextEdit_Msg"))
            
        if not s.value("comboBox_cloudType") is None:
            self.comboBox_cloudType.setCurrentText(s.value("comboBox_cloudType"))

        s.endGroup()
        s.endGroup()

    def on_DiscoverStartd(self):
        self.pushButton_Search.setText("停止扫描")
       
    def on_DiscoverStopped(self):
        self.pushButton_Search.setText("扫描设备")
        self.label_Tip.setText("Scanning stopped!")
    
    def __CheckDeviceFilter(self, name, address):
        if self.lineEdit_filter.text() == "" or self.lineEdit_filter.text() in name or self.lineEdit_filter.text() in address:
            return False
        
        return True
            
    def on_DeviceDiscovered(self, bleDeviceInfo:BleDeviceInfo):
        #判断设备是否已存在
        for i in range(self.tableWidget_Devices.rowCount()):
            address = self.tableWidget_Devices.item(i, 1).text()
            
            if bleDeviceInfo.address == address:
                return
                
        currentRow = self.tableWidget_Devices.rowCount()
        self.tableWidget_Devices.insertRow(currentRow)

        self.tableWidget_Devices.setItem(currentRow, 0, QTableWidgetItem(bleDeviceInfo.name))
        self.tableWidget_Devices.setItem(currentRow, 1, QTableWidgetItem(bleDeviceInfo.address))
        self.tableWidget_Devices.setItem(currentRow, 2, QTableWidgetItem(str(bleDeviceInfo.rssi)))
                    
        if self.__CheckDeviceFilter(bleDeviceInfo.name, bleDeviceInfo.address):
            self.tableWidget_Devices.setRowHidden(currentRow, True)
    
    def MsgAnalyse(self, msg):
        try:
            doc = json.loads(msg)
            if doc is None:
                return
        
            if not "action" in doc:
                return
        
            if not "params" in doc:
                return
        
            action = doc["action"]
            if "smartScanResponse" == action:
                params = doc["params"]
                if not "ssid" in params:
                    return
            
                wifi_list = params["ssid"]
                for i in range(len(wifi_list)):
                    wifi = wifi_list[i]
                    if "ssid" in wifi:
                        self.comboBox_SSID.addItem(wifi["ssid"])
        except:
            pass
                
    def SendMsg(self, msg):
        if (self.__bleClient is None):
            return
        
        self.__bleClient.SendMsg(msg)
        
        self.__sentColor = BleFunctionWindow.DefaultColor if self.__sentColor == BleFunctionWindow.ChangeColor else BleFunctionWindow.ChangeColor

        tf = self.plainTextEdit_MsgSent.currentCharFormat()
        tf.setForeground(self.__sentColor)
        self.plainTextEdit_MsgSent.setCurrentCharFormat(tf)
        
        self.plainTextEdit_MsgSent.appendPlainText(QDateTime.currentDateTime().toString("[yyyy-MM-dd HH:mm:ss:zzz]:") + msg)
        
    def RecvMsg(self, msg):
        self.MsgAnalyse(msg)
        self.__recvColor = BleFunctionWindow.DefaultColor if self.__recvColor == BleFunctionWindow.ChangeColor else BleFunctionWindow.ChangeColor

        tf = self.plainTextEdit_MsgReceived.currentCharFormat()
        tf.setForeground(self.__recvColor)
        self.plainTextEdit_MsgReceived.setCurrentCharFormat(tf)
        
        self.plainTextEdit_MsgReceived.appendPlainText(QDateTime.currentDateTime().toString("[yyyy-MM-dd HH:mm:ss:zzz]:") + msg)
        
    @Slot(str)
    def on_lineEdit_filter_textChanged(self, txt):
        for i in range(self.tableWidget_Devices.rowCount()):
            name = self.tableWidget_Devices.item(i, 0).text()
            address = self.tableWidget_Devices.item(i, 1).text()
            
            if self.__CheckDeviceFilter(name, address):
                self.tableWidget_Devices.setRowHidden(i, True)
            else:
                self.tableWidget_Devices.setRowHidden(i, False)
            
    @Slot()
    def on_pushButton_Search_clicked(self):
        if "扫描设备" == self.pushButton_Search.text():
            self.tableWidget_Devices.setRowCount(0)
            self.tableWidget_Devices.setFocus(Qt.TabFocusReason)

            self.label_Tip.setText("Scanning for devices ...")
            self.__bleFunction.StartDiscover()
        else:
            self.__bleFunction.StopDiscover()
    
    @Slot()
    def on_pushButton_GetDeviceWiFi_clicked(self):
        self.comboBox_SSID.clear()
        self.SendMsg('{"action":"smartScan","params":{}}')
        
    @Slot()
    def on_pushButton_SendWiFi_clicked(self):
        s = QSettings(Config.ConfigIniPath(), QSettings.IniFormat)
        s.beginGroup("UI")
        s.beginGroup("BleFunctionWindow")

        s.setValue("lineEdit_Pwd", self.lineEdit_Pwd.text())
        s.setValue("comboBox_cloudType", self.comboBox_cloudType.currentText())

        s.endGroup()
        s.endGroup()
        
        self.SendMsg('{"action":"smartConfig","params":{"ssid":"%s","key":"%s","cloudType":%d}}' % (self.comboBox_SSID.currentText(), self.lineEdit_Pwd.text(), self.comboBox_cloudType.currentIndex() + 1))
    
    @Slot()
    def on_pushButton_SendMsg_clicked(self):
        s = QSettings(Config.ConfigIniPath(), QSettings.IniFormat)
        s.beginGroup("UI")
        s.beginGroup("BleFunctionWindow")

        s.setValue("plainTextEdit_Msg", self.plainTextEdit_Msg.toPlainText())

        s.endGroup()
        s.endGroup()
        
        self.SendMsg(self.plainTextEdit_Msg.toPlainText())

    @Slot(QTableWidgetItem)
    def on_tableWidget_Devices_itemDoubleClicked(self, item):
        curRow = item.row()
        name = self.tableWidget_Devices.item(curRow, 0).text()
        address = self.tableWidget_Devices.item(curRow, 1).text()
        
        bleDeviceInfo = BleDeviceInfo()
        bleDeviceInfo.name = name
        bleDeviceInfo.address = address

        if (self.__bleClient is not None):
            self.__bleClient.Close()
            
        self.__bleClient = None
        self.__bleClient = BleClient(bleDeviceInfo)
        self.__bleClient.Connected.connect(self.on_Connected)
        self.__bleClient.ConnectFailed.connect(self.on_ConnectFailed)
        self.__bleClient.Disconnected.connect(self.on_Disconnected)
        self.__bleClient.DataReceived.connect(self.on_DataReceived)
    
    @Slot()
    def on_pushButton_ClearSent_clicked(self):
        self.plainTextEdit_MsgSent.clear()
    
    @Slot()
    def on_pushButton_ClearReceived_clicked(self):
        self.plainTextEdit_MsgReceived.clear()
    
    @Slot(BleDeviceInfo)
    def on_Connected(self, bleDeviceInfo:BleDeviceInfo):
        self.label_CurrentDevice.setText(bleDeviceInfo.name + "(" + bleDeviceInfo.address + ")")
        self.comboBox_SSID.clear()
        
    @Slot()
    def on_ConnectFailed(self):
        if (self.__bleClient is not None):
            self.__bleClient.Close()
            
        self.__bleClient = None
        self.label_CurrentDevice.clear()
        self.comboBox_SSID.clear()

    @Slot()
    def on_Disconnected(self):
        if (self.__bleClient is not None):
            self.__bleClient.Close()
            
        self.__bleClient = None
        self.label_CurrentDevice.clear()
        self.comboBox_SSID.clear()
       
    @Slot(str)
    def on_DataReceived(self, msg):
        self.RecvMsg(msg)
